package mac5789;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import mac5789.hamcycle.FixedRunsHamCycleMeasurer;
import mac5789.hamcycle.HamCycleExperiment;
import mac5789.hamcycle.HamCycleMeasurer;
import mac5789.hamcycle.HamCycleToSat;
import mac5789.phase.CachingMeasurer;
import mac5789.phase.FixedRunsSatisfiabilityMeasurer;
import mac5789.phase.PhaseChangeExperiment;
import mac5789.phase.SatisfiabilityMeasurer;
import mac5789.solver.MiniSatSolver;
import mac5789.solver.SatSolver;
import mac5789.utils.Range;

public class Start {


    public static void main(String... args) {
    	System.out.println("\n\n\n\n\n\n\n\nPHASE CHANGE EXPERIMENT\n\n\n\n\n\n\n\n");
    	phaseChangeExperiment(200);
    	System.out.println("\n\n\n\n\n\n\n\nHAMCYCLE EXPERIMENT\n\n\n\n\n\n\n\n");
        hamCycleExperiment(new Range(5, 50, 5));
        

    	System.out.println("\n\n\n\n\n\n\n\nENHANCED PHASE CHANGE EXPERIMENT\n\n\n\n\n\n\n\n");
    	phaseChangeExperiment(100000);
    	System.out.println("\n\n\n\n\n\n\n\nENHANCED HAMCYCLE EXPERIMENT\n\n\n\n\n\n\n\n");
        hamCycleExperiment(new Range(1, 50, 1));
    }

	private static void hamCycleExperiment(Range degrees) {
        int threads = 1;
        long seed = System.currentTimeMillis();
		int runs = 200;
        int vertexes = 50;

        SatSolver solver = new MiniSatSolver();
        ExecutorService executor = new ThreadPoolExecutor(threads, threads, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>());
        HamCycleToSat converter = new HamCycleToSat();
        HamCycleMeasurer measurer = new FixedRunsHamCycleMeasurer(solver, converter, executor, seed, runs);
        HamCycleExperiment experiment = new HamCycleExperiment(measurer, vertexes, degrees);
        experiment.execute();
        executor.shutdown();
	}
	
	private static void phaseChangeExperiment(int runs) {
		int threads = 4;
		long seed = System.currentTimeMillis();
		int variablesPerProblem = 100;
		
		SatSolver solver = new MiniSatSolver();
		ExecutorService executor = new ThreadPoolExecutor(threads, threads, 1000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>());
		SatisfiabilityMeasurer measurer = new CachingMeasurer(new FixedRunsSatisfiabilityMeasurer(solver, executor, seed, runs));
		PhaseChangeExperiment experiment = new PhaseChangeExperiment(measurer, variablesPerProblem);
		experiment.execute();
		executor.shutdown();
	}
}
